package org.smart4j.aop.proxy.jdkdynamicproxy.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 前面 staticproxy 包里写了一个静态代理，用这方法写下去项目中到处都有XxxProxy的影子。直到有一天架构师
 * 看到这代码一定会惊呆！他会告诉你：你怎么这么喜欢用静态代理呢？你就不会用动态代理，全部给我重构。
 * 然后你假装点点头说：“好的”。然而你根本都不知道什么叫静态代理和动态代理。
 * 于是你翻开了那边垫电脑桌子的设计模式，仔细一看原来到处都是XxxProxy的影子是因为你一直都在用静态代理，
 * 怪不得你老大让你重构。
 *
 * 要使用动态代理得实现：InvocationHandler 覆盖invoke方法
 * Created by lyc on 2016-04-04.
 */
public class DynamicProxy implements InvocationHandler {

    private Object target; //目标对象

    /**
     * 通过构造函数来初始化(
     * 现在流行叫"注入"了，"射入"更加形象；
     * 构造方法初始化叫："正着射"，所以反射初始化叫:"反着射"，简称:"反射"
     * )
     * @param target  被代理的目标对象
     */
    public DynamicProxy(Object target){
        this.target=target;
    }

    /**
     *JRE给我们"射"进来的，在该方法中，直接通过反射去invoke method，在调用前后分别处理
     * before、after方法。最后放回给result
     * @param proxy  代理对象
     * @param method 代理方法
     * @param args   对象数组
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result=method.invoke(target,args);
        after();
        return null;
    }
    /**
     * 重构  Proxy.newProxyInstance方法
     */
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this
        );
    }

    /**
     * 执行前方法
     */
    private  void before(){
        System.out.println("Before");
    }

    /**
     * 执行后方法
     */
    private  void after(){
        System.out.println("After");
    }
}
